package com.own.demo.lwf.utils.workUtils;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期工具类
 * 使用LocalDateTime存取或判断
 * **/
@Component
public class DateUtil2 {
    //判断slot1与slot2时间段有交叉
    public static boolean overlapped(TimeSlot slot1, TimeSlot slot2) {
        TimeSlot previous, next;
        previous = slot1.startTime.isBefore(slot2.startTime) ? slot1 : slot2;
        next = slot2.startTime.isAfter(slot1.startTime) ? slot2 : slot1;
        /**这里业务需要，允许时间点的重叠
         * 例如某个时间段的起始时间：2020-06-29 00:00:00
         * 和另一个时间段的终止时间：2020-06-29 00:00:00
         * 它们俩可以有交点。
         * 如果不需要这种逻辑只把le改成lt，ge改成gt就可
         * */
        return !(lt(previous, next) || gt(previous, next));
    }

    //取出月份的最后一天
    public static Date getLastDay(String year,String month) {
       Calendar cal= Calendar.getInstance();
       cal.set(Calendar.YEAR ,Integer.parseInt(year));
       cal.set(Calendar.MONTH ,Integer.parseInt(month)-1);
       cal.set(Calendar.DAY_OF_MONTH ,cal.getActualMaximum(Calendar.DATE));
       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
       Date date = DateUtil.str2Date(sdf.format(cal.getTime()),"yyyy-MM-dd");
       return date;
    }

    //取出一个时间段内存在的月份
    public static List<String> getMonthBetween(String RminDate, String RmaxDate){
        ArrayList<String> result = new ArrayList<String>();
        int rminDate = SzTrtUtil.numString(RminDate);
        int rmaxDate = SzTrtUtil.numString(RmaxDate);
        String minDate,maxDate;
        if(rminDate > rmaxDate){
            minDate = RmaxDate;
            maxDate = RminDate;
        }else {
            minDate = RminDate;
            maxDate = RmaxDate;
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月
            Calendar min = Calendar.getInstance();
            Calendar max = Calendar.getInstance();
            try {
                min.setTime(sdf.parse(minDate));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

            max.setTime(sdf.parse(maxDate));
            max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

            Calendar curr = min;
            while (curr.before(max) ) {
                result.add(sdf.format(curr.getTime()));
                curr.add(Calendar.MONTH, 1);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return result;
    }

    //判断月份差值
    public static int getMonthDiffOld(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);
        int year1 = c1.get(Calendar.YEAR);
        int year2 = c2.get(Calendar.YEAR);
        int month1 = c1.get(Calendar.MONTH);
        int month2 = c2.get(Calendar.MONTH);
        int day1 = c1.get(Calendar.DAY_OF_MONTH);
        int day2 = c2.get(Calendar.DAY_OF_MONTH);
        // 获取年的差值
        int yearInterval = year1 - year2;
        // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 得到相差的年数
        if (month1 < month2 || month1 == month2 && day1 < day2) {
            yearInterval--;
        }
        // 获取月数差值
        int monthInterval = (month1 + 12) - month2;
        if (day1 < day2) {
            monthInterval--;
        }
        monthInterval %= 12;
        int monthsDiff = Math.abs(yearInterval * 12 + monthInterval);
        return monthsDiff;
    }

    //判断月份差值(不考虑天的影响)
    public static int getMonthDiff(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);
        int year1 = c1.get(Calendar.YEAR);
        int year2 = c2.get(Calendar.YEAR);
        int month1 = c1.get(Calendar.MONTH);
        int month2 = c2.get(Calendar.MONTH);

        // 获取年的差值
        int yearInterval = year1 - year2;

        if (month1 < month2 ) {
            yearInterval--;
        }
        // 获取月数差值
        int monthInterval = (month1 + 12) - month2;

        monthInterval %= 12;
        int monthsDiff = Math.abs(yearInterval * 12 + monthInterval);
        return monthsDiff;
    }

    //判断月份差值允许负数(不考虑天的影响)
    public static int getMonthDiffFu(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);
        int year1 = c1.get(Calendar.YEAR);
        int year2 = c2.get(Calendar.YEAR);
        int month1 = c1.get(Calendar.MONTH);
        int month2 = c2.get(Calendar.MONTH);

        // 获取年的差值
        int yearInterval = year1 - year2;
        // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 得到相差的年数
        if (month1 < month2 ) {
            yearInterval--;
        }
        // 获取月数差值
        int monthInterval = (month1 + 12) - month2;

        monthInterval %= 12;
        int monthsDiff = yearInterval * 12 + monthInterval;
        return monthsDiff;
    }
    /**
     * 构造一个时间段
     * @param startTime
     * @param endTime
     * @return
     */
    public static TimeSlot buildSlot(LocalDateTime startTime, LocalDateTime endTime) {
        return new TimeSlot(startTime, endTime);
    }

    /**
     * less equal
     * 小于等于
     * @param prev
     * @param next
     * @return
     */
    private static boolean le(TimeSlot prev, TimeSlot next) {
        return lt(prev, next) || next.endTime.isEqual(prev.startTime);
    }

    /**
     * greater equal
     * 大于等于
     * @param prev
     * @param next
     * @return
     */
    private static boolean ge(TimeSlot prev, TimeSlot next) {
        return gt(prev, next) || prev.endTime.isEqual(next.startTime);
    }

    /**
     * greater than
     * 大于
     * @param prev
     * @param next
     * @return
     */
    private static boolean gt(TimeSlot prev, TimeSlot next) {
        return prev.endTime.isBefore(next.startTime);
    }

    /**
     * less than
     * 小于
     * @param prev
     * @param next
     * @return
     */
    private static boolean lt(TimeSlot prev, TimeSlot next) {
        return next.endTime.isBefore(prev.startTime);
    }

    /**
     * 时间段类
     */
    @Data
    public static class TimeSlot{
        private LocalDateTime startTime;
        private LocalDateTime endTime;

        public TimeSlot(LocalDateTime startTime, LocalDateTime endTime) {
            if (startTime.isAfter(endTime)) {
                this.startTime = endTime;
                this.endTime = startTime;
            } else {
                this.startTime = startTime;
                this.endTime = endTime;
            }
        }
    }


    /**
     * Date类型转换成LocalDateTime类型
     */
    public static LocalDateTime dateTrans(Date date) {
        Instant instant = date.toInstant();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.ofOffset("GMT", ZoneOffset.ofHours(8)));
        return localDateTime;
    }

    public static int getDifferenceMonths(String time1, String time2){

        try {
            //正则校验入参格式..
            String bigStr;
            String lowStr;
            //判断年份大小
            if (Integer.parseInt(time1) > Integer.parseInt(time2)) {
                bigStr = time1;
                lowStr = time2;
            } else {
                bigStr = time2;
                lowStr = time1;
            }

            String bigYearStr1 = bigStr.substring(0, 4);
            String bigMonthStr1 = bigStr.substring(4, 6);
            String lowYearStr2 = lowStr.substring(0, 4);
            String lowMonthStr2 = lowStr.substring(4, 6);

            int bigYear = Integer.parseInt(bigYearStr1);
            int bigMonth = Integer.parseInt(bigMonthStr1);
            int lowYear = Integer.parseInt(lowYearStr2);
            int lowMoth = Integer.parseInt(lowMonthStr2);

            //月份差
            int range = 0;
            //数字型结果月份
            int resMonth = 0;
            //字符型结果月份
            String resMonthStr = "";

            int time = 0;

            //同一年份
            if (bigYear == lowYear) {
                range = bigMonth - lowMoth;
                for (int i = 1; i < range; i++) {
                    //差值月份
                    resMonth = lowMoth + i;
                    //小于10的月份要补0
                    resMonthStr = resMonth > 9 ? "" + resMonth : "0" + resMonth;
                    time++;
                }
            }//年份是连续的
            else if (bigYear - lowYear == 1) {
                //小年月份距离12月的位置
                range = 12 - lowMoth;
                //小年份到年底十二月
                for (int i = 1; i <= range; i++) {
                    //差值月份
                    resMonth = lowMoth + i;
                    //小于10的月份要补0
                    resMonthStr = resMonth > 9 ? "" + resMonth : "0" + resMonth;
                    time++;
                }
                //大年份初到大年份当前
                for (int i = 1; i < bigMonth; i++) {
                    resMonth = i;
                    resMonthStr = resMonth > 9 ? "" + resMonth : "0" + resMonth;
                    time++;
                }

            }
            //年份是不连续的 2020 2025
            else {
                //计算中间整数倍的差值年份
                int yearRange = bigYear - lowYear;
                int tempYear = 0;
                String tempYearStr = "";
                String tempMonthStr = "";
                //外层控制年份
                for (int i = 1; i < yearRange; i++) {
                    tempYear = lowYear + i;
                    tempYearStr = "" + tempYear;
                    //内层控制年份
                    for (int j = 1; j <= 12; j++) {
                        tempMonthStr = j > 9 ? "" + j : "0" + j;
                        time++;
                    }
                }

                //计算两边的差值月份 复用连续年份的算法
                //小年月份距离12月的位置
                range = 12 - lowMoth;
                //小年份到年底十二月
                for (int i = 1; i <= range; i++) {
                    //差值月份
                    resMonth = lowMoth + i;
                    //小于10的月份要补0
                    time++;
                }
                //大年份初到大年份当前
                for (int i = 1; i < bigMonth; i++) {
                    resMonth = i;
                    time++;
                }
            }

            return time;
        } catch (Exception e) {
            return 0;
        }
    }
}
